package com.javastar.modules.user.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.javastar.common.bean.EntityStateBean;
import com.javastar.common.bean.LoginUser;
import com.javastar.common.enums.RegexEnum;
import com.javastar.common.enums.TokenEnum;
import com.javastar.common.exception.AssertUtil;
import com.javastar.common.exception.ErrorCode;
import com.javastar.common.utils.JwtUtil;
import com.javastar.common.utils.TokenUtil;
import com.javastar.common.utils.ValidatorUtils;
import com.javastar.modules.user.entity.UserEntity;
import com.javastar.modules.user.mapper.UserMapper;
import com.javastar.modules.user.service.UserService;
import com.javastar.modules.user.to.UsernameLoginTO;
import com.javastar.modules.user.vo.ReturnUserVO;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 用户
 *
 * @author zxx
 * @date 2023/7/23
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {
    /**
     * 手机号或邮箱和密码登陆
     *
     * @param usernameLoginTO
     * @param response
     * @return
     */
    @Override
    public ReturnUserVO phoneOrEmailAndPasswordLogin(UsernameLoginTO usernameLoginTO, HttpServletResponse response) {
        /* 先使用正则匹配判断是手机号还是邮箱登陆；判断登陆正确性；错误处理；生成token；保存cookie */
        boolean isPhone = false;
        // 邮箱登陆
        if (ReUtil.isMatch(RegexEnum.EMAIL.getRegex(), usernameLoginTO.getUsername())) {
            isPhone = false;
        } else if (ReUtil.isMatch(RegexEnum.PHONE.getRegex(), usernameLoginTO.getUsername())) {
            // 手机号登陆
            isPhone = true;
        }

        UserEntity user = lambdaQuery().eq(isPhone, UserEntity::getPhone, usernameLoginTO.getUsername())
                .eq(!isPhone, UserEntity::getEmail, usernameLoginTO.getUsername())
                .eq(UserEntity::getUserPassword, SecureUtil.md5(usernameLoginTO.getPassword()))
                .one();

        if (ValidatorUtils.isEmpty(user)) {
            AssertUtil.error(ErrorCode.USERNAME_OR_PASSWORD_ERROR);
        }

        // 禁用
        if (user.getState() == EntityStateBean.UserState.FORBIDDEN.getState()) {
            AssertUtil.error(ErrorCode.USER_ALREADY_FORBIDDEN);
        }

        // 登录成功，生成token，保存cookie
        LoginUser loginUser = new LoginUser();
        loginUser.setId(user.getId());
        loginUser.setNickname(user.getNickname());
        String userToken = JwtUtil.generateToken(loginUser, TokenEnum.USER_TOKEN);
        Cookie tokenCookie = new Cookie(TokenEnum.USER_TOKEN.getTokenKey(), userToken);
        tokenCookie.setPath("/");
        tokenCookie.setMaxAge(TokenUtil.getCookieAgeFromTokenExpire(TokenEnum.USER_TOKEN.getExpireTime()));
        response.addCookie(tokenCookie);

        ReturnUserVO returnUserVO = new ReturnUserVO();
        returnUserVO.setUserNickname(user.getNickname());
        returnUserVO.setUserId(user.getId());
        returnUserVO.setToken(userToken);
        returnUserVO.setExpireDate(DateUtil.offsetDay(new Date(), 7));

        return returnUserVO;
    }
}
